// This file is part of OpenTSDB.
// Copyright (C) 2017 TeleDB Development Group.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or (at your
// option) any later version.  This program is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
// General Public License for more details.  You should have received a copy
// of the GNU Lesser General Public License along with this program.  If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.tools.http;


public class TSDBConfig {

    private String url;
    private int port;
    private int putRequestLimit;
    private boolean putRequestLimitSwitch;
    private int ioThreadCount;
    private int httpConnectionPool;
    private int httpConnectTimeout;
    private int httpConnectionLiveTime;
    private int batchPutConsumerThreadCount;
    private int batchPutRetryCount;
    private int batchPutSize;
    private int batchPutTimeLimit;
    private int batchPutBufferSize;

    private TSDBConfig() {

    }



    public static TSDBConfig.TSDBConfigBuilder builder(String url) {
        return new TSDBConfig.TSDBConfigBuilder(url);
    }


    public String getUrl() {
        return url;
    }

    public int getPort() {
        return port;
    }

    public int getIoThreadCount() {
        return ioThreadCount;
    }

    public int getHttpConnectionPool() {
        return httpConnectionPool;
    }

    public int getHttpConnectTimeout() {
        return httpConnectTimeout;
    }

    public int getHttpConnectionLiveTime() {
        return httpConnectionLiveTime;
    }

    public int getBatchPutConsumerThreadCount() {
        return batchPutConsumerThreadCount;
    }

    public int getBatchPutRetryCount() {
        return batchPutRetryCount;
    }

    public int getBatchPutSize() {
        return batchPutSize;
    }

    public int getBatchPutTimeLimit() {
        return batchPutTimeLimit;
    }

    public int getBatchPutBufferSize() {
        return batchPutBufferSize;
    }

    public int getPutRequestLimit() {
        return putRequestLimit;
    }

    public boolean isPutRequestLimitSwitch() {
        return putRequestLimitSwitch;
    }

    public static class TSDBConfigBuilder {
        private String url;
        private int port = 8585;
        private int putRequestLimit = -1;
        private boolean putRequestLimitSwitch = true;
        private int httpConnectionPool = 64;
        private int httpConnectTimeout = 90000;
        private int httpConnectionLiveTime = 90000;
        private int ioThreadCount = 1;
        public static volatile boolean ProducerThreadSerializeSwitch = false;

        private boolean httpCompress = false;
        private int batchPutRetryCount = 1;
        // 流量限制，设置每秒最大提交 Point 的个数。
        private int maxTPS = 1000;
        // 异步写开关。默认为 false。推荐异步写
        private boolean asyncPut = false;
        // 异步写相关，客户端缓冲队列长度，默认为10000。
        private int batchPutBufferSize = 10000;
        // 异步写相关，缓冲队列消费线程数，默认为 1。
        private int batchPutConsumerThreadCount = 5;
        // 异步写相关，每次批次提交给客户端点的个数，默认为 500。
        private int batchPutSize = 50;
        // 异步写相关，每次等待最大时间限制，单位为 ms，默认为 300。
        private int batchPutTimeLimit = 300;

        public TSDBConfig build() {
            TSDBConfig tsdbConfig = new TSDBConfig();
            tsdbConfig.url = this.url;
            tsdbConfig.port = this.port;
            tsdbConfig.batchPutRetryCount = this.batchPutRetryCount;
            tsdbConfig.putRequestLimitSwitch = this.putRequestLimitSwitch;
            tsdbConfig.putRequestLimit = this.putRequestLimit;
            tsdbConfig.ioThreadCount = this.ioThreadCount;
            tsdbConfig.httpConnectionPool = this.httpConnectionPool;
            tsdbConfig.httpConnectTimeout = this.httpConnectTimeout;
            tsdbConfig.httpConnectionLiveTime = this.httpConnectionLiveTime;
            tsdbConfig.batchPutConsumerThreadCount = this.batchPutConsumerThreadCount;
            tsdbConfig.batchPutSize = this.batchPutSize;
            tsdbConfig.batchPutTimeLimit = this.batchPutTimeLimit;
            tsdbConfig.batchPutBufferSize = this.batchPutBufferSize;
            if (this.putRequestLimitSwitch && this.putRequestLimit <= 0) {
                tsdbConfig.putRequestLimit = this.httpConnectionPool;
            }
            return tsdbConfig;
        }

        public TSDBConfigBuilder(String url) {
            this.url = url;
        }

        public TSDBConfigBuilder httpConnectionPool(int connectionPool) {
            if (connectionPool <= 0) {
                throw new IllegalArgumentException("The ConnectionPool con't be less then 1");
            }
            httpConnectionPool = connectionPool;
            return this;
        }

        public TSDBConfigBuilder httpConnectTimeout(int httpConnectTimeout) {
            this.httpConnectTimeout = httpConnectTimeout;
            return this;
        }

        public TSDBConfigBuilder ioThreadCount(int ioThreadCount) {
            this.ioThreadCount = ioThreadCount;
            return this;
        }

        public TSDBConfigBuilder setHost(String url) {
            this.url = url;
            return this;
        }

        public TSDBConfigBuilder setPort(int port) {
            this.port = port;
            return this;
        }

        public TSDBConfigBuilder putRequestLimit(int limit) {
            this.putRequestLimit = limit;
            this.putRequestLimitSwitch = true;
            return this;
        }

        public TSDBConfigBuilder closePutRequestLimit() {
            this.putRequestLimitSwitch = false;
            return this;
        }

        public TSDBConfigBuilder setIoThreadCount(int ioThreadCount) {
            this.ioThreadCount = ioThreadCount;
            return this;
        }

        public TSDBConfigBuilder batchPutConsumerThreadCount(int batchPutConsumerThreadCount) {
            this.batchPutConsumerThreadCount = batchPutConsumerThreadCount;
            return this;
        }

        public TSDBConfigBuilder httpCompress(boolean httpCompress) {
            this.httpCompress = httpCompress;
            return this;
        }

        public TSDBConfigBuilder openHttpCompress() {
            this.httpCompress = true;
            return this;
        }

        public TSDBConfigBuilder batchPutRetryCount(int batchPutRetryCount) {
            this.batchPutRetryCount = batchPutRetryCount;
            return this;
        }

        public TSDBConfigBuilder batchPutTimeLimit(int batchPutTimeLimit) {
            this.batchPutTimeLimit = batchPutTimeLimit;
            return this;
        }

        public TSDBConfigBuilder asyncPut(boolean asyncPut) {
            this.asyncPut = asyncPut;
            return this;
        }

        public TSDBConfigBuilder batchPutBufferSize(int batchPutBufferSize) {
            this.batchPutBufferSize = batchPutBufferSize;
            return this;
        }

    }
}
